package org.xxpay.pay.channel.dwf;

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.entity.PayOrder;
import org.xxpay.pay.channel.BasePayNotify;
import org.xxpay.pay.channel.dwf.util.EncodeUtil;
import org.xxpay.pay.channel.shengfutong.SftpayConfig;
import org.xxpay.pay.channel.swiftpay.util.JsonUtil;

@Service
public class DwfPayNotifyService extends BasePayNotify {

    private final static String logPrefix = "【DWF】";

    @Override
    public String getChannelName() {
        return DwfConfig.CHANNEL_NAME;
    }

    @Override
    public JSONObject doNotify(Object notifyData) {
        _log.info("====== 开始处理DWF支付回调通知 ======");
        JSONObject bizContext = getRequestParameters(notifyData);
        JSONObject payContext = verifyPayParams(bizContext);
        JSONObject retObj = buildFailRetObj();
        if (payContext == null) {
            retObj.put(PayConstant.RESPONSE_RESULT, SftpayConfig.RESPONSE_RESULT_FAIL);
            return retObj;
        }
        PayOrder payOrder = (PayOrder) bizContext.get("payOrder");
        byte payStatus = payOrder.getStatus(); // 0：订单生成，1：支付中，-1：支付失败，2：支付成功，3：业务处理完成，-2：订单过期
        if (payStatus != PayConstant.PAY_STATUS_SUCCESS && payStatus != PayConstant.PAY_STATUS_COMPLETE) {
            int updatePayOrderRows = rpcCommonService.rpcPayOrderService.updateStatus4Success(payOrder.getPayOrderId());
            if (updatePayOrderRows != 1) {
                _log.error("{}更新支付状态失败,将payOrderId={},更新payStatus={}失败", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
                retObj.put(PayConstant.RESPONSE_RESULT, "处理订单失败");
                return retObj;
            }
            _log.error("{}更新支付状态成功,将payOrderId={},更新payStatus={}成功", logPrefix, payOrder.getPayOrderId(), PayConstant.PAY_STATUS_SUCCESS);
            payOrder.setStatus(PayConstant.PAY_STATUS_SUCCESS);
            _log.info("{}通知参数:{}", logPrefix, JsonUtil.objectToJson(bizContext));
            // 业务系统后端通知
            baseNotify4MchPay.doNotify(payOrder, true);
            _log.info("====== 完成处理dwfpay支付回调通知 ======");
            retObj.put(PayConstant.RESPONSE_RESULT, "000000");
        }
        return retObj;
    }

    private JSONObject verifyPayParams(JSONObject bizContext) {
        String payOrderId = bizContext.getString("traceId");
        PayOrder payOrder = rpcCommonService.rpcPayOrderService.findByPayOrderId(payOrderId);
        if (payOrder == null) {
            _log.error("Can't found payOrder form db. payOrderId={}, ", payOrderId);
            bizContext.put("retMsg", "Can't found payOrder");
            return null;
        }
        DwfConfig dwfConfig = new DwfConfig(getPayParam(payOrder));
        //回调的加密参数
        String encryptData = bizContext.getString("encryptData");
        //回调的签名参参数
        String signData = bizContext.getString("signData");
        String privateKey = dwfConfig.getPrivateKey();
        /*解密出来明文JSON*/
        String plainText = EncodeUtil.decode(encryptData, privateKey.substring(0, 16));
        boolean flag = EncodeUtil.checkSign(plainText, signData, privateKey.substring(16));
        if (!flag) {
            _log.error("验证签名失败. payOrderId={}, ", payOrderId +"验证签名失败" + "上游签名”" + signData);
            bizContext.put("retMsg", "验证签名失败");
            return null;
        }
        JSONObject payContext = (JSONObject) JsonUtil.jsonToBean(plainText, JSONObject.class);
        if (!"01".equals(payContext.getString("orderStatus"))) {
            _log.error("订单{}交易失败，回调内容", payOrderId,bizContext.toJSONString());
            bizContext.put("retMsg", "订单{}交易失败");
            return null;
        }


        // 核对金额
        long outPayAmt = payContext.getLong("payAmount");
        long dbPayAmt = payOrder.getAmount().longValue();
        if (dbPayAmt != outPayAmt) {
            _log.error("金额不一致. outPayAmt={},transOrderId={}", outPayAmt, payOrderId);
            payContext.put("retMsg", "金额不一致");
            return null;
        }
        bizContext.put("payOrder", payOrder);
        return payContext;
    }



}
